#include "GY_ObjectGroup.h"
#include "Graphics/GY_GraphicsReflection.h"
#include "Graphics/FormulaCalculation/GY_CalculationClass.h"


GY_ObjectGroup::GY_ObjectGroup(const QString &guid, QGraphicsItem *parent)
    : GY_ContainerTransform(guid,this,parent)
{
    m_pTransformationClass = new GY_TransformationClass(this);
    m_pCalculationClass = new GY_CalculationClass(this);
    initializationPropertyInfo();
    this->setCenterPointF(m_PropertyInfoMap["Position"].propertyValue.toPointF());
    connect(this,&GY_ObjectGroup::executionInformationSig,this,&GY_ObjectGroup::getExecutionInformation);
    GY_Object::setUserData(GY_ENUM::ObjectType,QVariant::fromValue(2));
}

GY_ObjectGroup::~GY_ObjectGroup()
{

}

bool GY_ObjectGroup::addAttribute(const QString &name, const QVariant &value)
{
    if(value.isNull()) {
        return false;
    }
    if(m_PropertyInfoMap.contains(name)) {
        return false;
    }
    GY_PropertyInfo Attribute(this);
    Attribute.propertyName = name;
    Attribute.propertyValue = value;
    Attribute.updateType = Update;
    Attribute.propertyType = getType(value);
    Attribute.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_ObjectGroup::updateAttribute;
    m_PropertyInfoMap.insert(name,Attribute);
    m_PropertyInfoMap[Attribute.propertyName].setConnect();
    m_pCalculationClass->formulaCalculation(name, Attribute.propertyType);
    m_pCalculationClass->propertyChange(name,value,Attribute.propertyType);
    BindingInformation b;
    b.varType = Attribute.propertyType;
    b.type = 0;
    b.pointName = '.' + name;
    m_biMap.insert(name,b);
    m_attributeMap.insert(name,value);
    return true;
}

bool GY_ObjectGroup::deleteAttribute(const QString &name)
{
    if(!m_PropertyInfoMap.contains(name)) {
        return false;
    }
    //判断name是否已经绑定
    QMap<QString,BindingInformation>::Iterator iter = m_biMap.begin();
    while(iter != m_biMap.end()) {
        if(iter.key() == name) {
            return false;
        }
        ++iter;
    }
    //删除全局变量
    m_pCalculationClass->deleteVar(name);
    m_PropertyInfoMap.remove(name);
    m_attributeMap.remove(name);
    return true;
}

QString GY_ObjectGroup::changeAttribute(const QString &name, const QVariant &value)
{
    if(!m_PropertyInfoMap.contains(name)) {
        return "There is no name in the m_PropertyInfoMap!";
    }
    //如果有绑定信息，check是否匹配
    if(m_biMap.contains(name)) {
        int bindNamePurposeSize = m_biMap[name].purpose.size();
        for(int i=0;i<bindNamePurposeSize;i++) {
            //不同类型不能绑定
            QStringList purTypeList =  m_biMap[name].purpose.at(i).split(".");
            //获取目的属性类型
            PropertyType purType = getPurposeType(purTypeList, m_ChildrensMap);
            //判断是否为点xy属性
            if((purTypeList.at(purTypeList.size()-1) == "X") || (purTypeList.at(purTypeList.size()-1) == "Y")) {
                purType = DoublePropertyType;
            }
            //判断类型是否匹配
            if(purType != getType(value)) {
                return QString("Property types do not match, and type change is not recommended!");
            }
        }
    }
    m_attributeMap[name] = value;
    m_PropertyInfoMap[name].propertyType = getType(value);
    m_PropertyInfoMap[name].propertyValue = value;

    //删除原全局变量，设置新变量
    m_pCalculationClass->deleteVar(name);
    m_biMap[name].varType = m_PropertyInfoMap[name].propertyType;
    m_pCalculationClass->formulaCalculation(name, m_PropertyInfoMap[name].propertyType);
    m_pCalculationClass->propertyChange(name,value,m_PropertyInfoMap[name].propertyType);
    updateAttribute(name,value);
    return "OK";
}

QString GY_ObjectGroup::dataFlowEditor(QString &source, const QString &purpose, int copy)
{
    int index1 = source.indexOf('.');
    int index2 = purpose.indexOf('.');
    QString str1 = source;
    QString str2 = purpose;
    if(!str1.contains("___0") && !str2.contains("___0")) {
        if(index1 != -1) {
            if(!str1.contains(".Element[")) {
                str1.insert(index1,"___0");
            }
        }
        if(index2 != -1) {
            str2.insert(index2,"___0");
        }
        dataFlowEditor(str1,str2);
    }

    //判断目的属性是否已经绑定
    QMap<QString,QVector<QString>>::Iterator iterPurpose = m_bindInformationMap.begin();
    while(iterPurpose != m_bindInformationMap.end()) {
        int iterPurposeValueSize = iterPurpose.value().size();
        for(int i=0;i<iterPurposeValueSize;i++) {
            if(iterPurpose.value().at(i) == purpose) {
                return QString(purpose + ": It already exists!");
            }
            //一段段比较
//            QStringList listBind = iterPurpose.value().at(i).split('.');
//            QStringList listPurpose = purpose.split('.');

//            if((listPurpose.size()!=listBind.size())&&(listBind.at(0)==listPurpose.at(0))&&(listBind.at(1)==listPurpose.at(1))) {
//                if((listBind.size()>listPurpose.size())&&(listBind.at(2)=="X"||listBind.at(2)=="Y")) {
//                    return QString(iterPurpose.value().at(i) + ": It already exists!");
//                }else if((listPurpose.size()>listBind.size())&&(listPurpose.at(2)=="X"||listPurpose.at(2)=="Y")) {
//                    return QString(iterPurpose.value().at(i) + ": It already exists!");
//                }
//            }
        }
        ++iterPurpose;
    }

    //数组替换复制组属性LoopIndex为01234等等，以复制组复制个数为准，分开绑定
    QRegExp rx("\\[[^\\]]*\\]");
    QStringList list;
    int pos = 0;
    while((pos = rx.indexIn(source,pos)) != -1) {
        QStringList l = rx.capturedTexts();
        QString str = l.at(0);
        str.remove(QChar('['));
        str.remove(QChar(']'));
        list.push_back(str);
        pos += rx.matchedLength();
    }

    //获取复制组复制图形的指针
    GY_Object* obj = nullptr;
    obj = getPurObject(purpose.split(".").at(0), obj, m_ChildrensMap);
    //找不到目的属性名称，返回哪个属性名称找不到
    if(obj == nullptr) {
        return QString(purpose + ": does not exist!");
    }

    QStringList l = purpose.split(".");
    QString purposeProperty;
    int lSize = l.size();
    for(int k=1;k<lSize;k++) {
        if(k == lSize-1) {
            purposeProperty += l.at(k);
            break;
        }
        purposeProperty += l.at(k) + ".";
    }
    obj->isBind.insert(purposeProperty,true);

    //获取图形复制个数
    int repeatNum = obj->getRepeatNum();
    //把原本的source存一下，防止source的值发生改变导致绑定失败
    QString primitiveSource = source;

    //绑定图形在复制组中的其他复制品
    for(int i=0;i<repeatNum;i++) {
        int listSize = list.size();
        //[]中LoopIndex替换为数字
        for(int j=0;j<listSize;j++) {
            if(!isPureNumber(list.at(j))) {
                source.replace(list.at(j),QString("%1").arg(i));
            }
        }
        //还有不在[]中的LoopIndex，替换为LoopIndex_1
        if(source.contains("LoopIndex")) {
            source.replace("LoopIndex",QString("LoopIndex_%1").arg(i));
        }
        //目的属性替换
        QString purposeChange = purpose;
        //替换为复制品的名称
        purposeChange.replace(purpose.split(".").at(0), QString(purpose.split(".").at(0)+"_+_=_%1").arg(i));
        //绑定复制组中复制品
        QString ret = dataFlowEditor(source,purposeChange,1);
        //复制品绑定是否成功
        if(ret != "OK") {
//            return ret;
        }
        source = primitiveSource;
    }

    //复制组中的原版图元
    if(repeatNum > 0) {
        int listSize = list.size();
        for(int j=0;j<listSize;j++) {
            if(!isPureNumber(list.at(j))) {
                copy = 1;
                if(m_bindInformationMap.contains(source)) {
                    m_bindInformationMap[source].push_back(purpose);
                }else {
                    QVector<QString> pur;
                    pur.push_back(purpose);
                    m_bindInformationMap.insert(source, pur);
                }
//                source.replace(list.at(j),QString("%1").arg(repeatNum-1));
            }
        }
        if(source.contains("LoopIndex")) {
            copy = 1;
            if(m_bindInformationMap.contains(source)) {
                m_bindInformationMap[source].push_back(purpose);
            }else {
                QVector<QString> pur;
                pur.push_back(purpose);
                m_bindInformationMap.insert(source, pur);
            }
//            source.replace("LoopIndex",QString("LoopIndex_%1").arg(repeatNum-1));
        }
        return "copy";
    }

    //不在复制组中图形与数组第一个绑定-------RepeatGroup_1.LoopIndex复制组这个属性锁定为0
    int listSize = list.size();
    for(int j=0;j<listSize;j++) {
        //[]中括号内不为纯数字,替换 0
        if((source.contains(list.at(j))) && (!isPureNumber(list.at(j)))) {
            source.replace(list.at(j),QString("%1").arg(0));
        }
    }
//    qDebug()<<source<<purpose<<repeatNum<<"绑定信息及复制个数";

    //储存绑定信息
    m_source = source;
    m_purpose = purpose;

    QVector<QString> tmpValueVec;//去第一个点后变量名test
    QVector<QString> tmpVec;//未修改变量名.test.x
    //source返回已改变字符串
    tmpVec = m_pTransformationClass->formulaTransformation(source,tmpValueVec);

    //去掉tmpVec和tmpValueVec中重复的数据
    for(int i=0;i<tmpVec.size();i++) {
        for(int j=i+1;j<tmpVec.size();j++) {
            if(tmpVec[j]==tmpVec[i]) {
                tmpVec.remove(i);
                tmpValueVec.remove(i);
                i--;
                break;
            }
        }
    }

    //替换子类属性变量名称,检查所有源属性是否存在,检查目的和源是否相同
    int tmpVecSize = tmpVec.size();
    for(int j=0;j<tmpVecSize;j++) {
        //子控件属性
        if(tmpVec.at(j).at(0) != '.') {
            //子类属性tmpValueVec加后面一段，和成一个变量name.property.x->name.property
            QStringList list = tmpVec.at(j).split(".");
            //判断名称属性是否存在name.property.pointxy
            if(!checkVarName(list, m_ChildrensMap)) {
                return QString(tmpVec.at(j) + ": does not exist!");
            }
            QString str1;
            QString str2;
            //textObjName_10.DataString.Capacity例外三段
            if((list.size() == 3) && (list.at(2) != "X") && (list.at(2) != "Y")) {
                str1 = list.at(0)+"."+list.at(1)+"."+list.at(2);
                str2 = list.at(0)+"_"+list.at(1)+"_"+list.at(2);
            }else {
                str1 = list.at(0)+"."+list.at(1);
                str2 = list.at(0)+"_"+list.at(1);
            }
            //特殊字符识别不到，替换为下划线
            str2.replace('[','_');
            str2.replace(']','_');
            str2.replace('*','_');
            source = source.replace(str1,str2);
            tmpValueVec.replace(j,str2);
        }else {
            QStringList list = tmpVec.at(j).split(".");
            list.removeFirst();

            //判断属性是否存在.property.pointxy
            if(!checkProName(list)) {
                return QString(tmpVec.at(j) + ": does not exist!");
            }
            m_bindVec.push_back(list.at(0));
        }
        //相同目的属性和源属性不能绑定
        if(isSameProperty(purpose, tmpVec.at(j))) {
            return QString(purpose + ": destination and source conflict!");
        }
    }

    //判断目的名称属性是否存在name.property.pointxy
    QStringList purList = purpose.split(".");
    if(!checkVarName(purList, m_ChildrensMap)) {
        obj->isBind.remove(purposeProperty);
        return QString(purpose + ": does not exist!");
    }

    //不同类型不能绑定
    QStringList purTypeList =  purpose.split(".");
    //获取目的属性类型
    PropertyType purType = getPurposeType(purTypeList, m_ChildrensMap);
    //判断是否为点xy属性
    if((purTypeList.at(purTypeList.size()-1) == "X") || (purTypeList.at(purTypeList.size()-1) == "Y")) {
        purType = DoublePropertyType;
    }
    //判断类型是否匹配
    if(!checkType(purType, tmpVec, m_ChildrensMap)) {
        obj->isBind.remove(purposeProperty);
        return QString("Property type mismatch!");
    }

    //设置全局变量
    setGloabalVariable(source,tmpValueVec,tmpVec,purpose);

    int i=0;
    int tmpValueVecSize = tmpValueVec.size();
    for(i=0;i<tmpValueVecSize;i++) {
        //子类属性信号关联
        if(m_biMap[tmpValueVec.at(i)].type == 1) {
            //源数据对象
            GY_Object* connectObj = nullptr;
            connectObj = getProObject(tmpValueVec.at(i), connectObj, m_ChildrensMap);
            //接收更新信号
            connect(connectObj,&GY_Object::updatePropertyEvent,this,[=](const GY_Object *,const QString &propertyName,
                    const QVariant &propertyValue,const PropertyType &type) {
//                qDebug()<<pObject<<propertyName<<propertyValue<<type;
                if(m_biMap[tmpValueVec.at(i)].source.size() == 0) {
                    return;
                }
                //判断改变的是否为绑定的item
                QStringList list = m_biMap[tmpValueVec.at(i)].pointName.split(".");
                //属性名称
                QString property;
                //点类型不需要加点后面的xy, position.x为position
                if(propertyValue.canConvert<QPointF>()) {
                    property += list.at(1);
                }else {
                    int listSize = list.size();
                    for(int k=1;k<listSize;k++) {
                        if(k == listSize-1) {
                            property += list.at(k);
                            break;
                        }
                        property += list.at(k) + ".";
                    }
                }
                //属性名称不同不给予操作
                if(propertyName != property) {
                    return;
                }
                m_pCalculationClass->propertyChange(tmpValueVec.at(i),propertyValue,type);
                QString executionInformation = m_pCalculationClass->getSourceValue(m_biMap,tmpValueVec.at(i));
                if(executionInformation != "OK") {
                    //数学表达式有错误
                    emit executionInformationSig(executionInformation);
                    obj->isBind.remove(purposeProperty);
                    return;
                }
                //目的item传值
                int m_biMapTmpValueVecSourceSize = m_biMap[tmpValueVec.at(i)].source.size();
                for(int j=0;j<m_biMapTmpValueVecSourceSize;j++) {
                    QVariant val = m_biMap[tmpValueVec.at(i)].value.at(j);
                    QString pur = m_biMap[tmpValueVec.at(i)].purpose.at(j);
                    QStringList list = pur.split(".");
                    QString purposeObjName = list.at(0);
                    QString purposeProperty;

                    int listSize = list.size();
                    for(int k=1;k<listSize;k++) {
                        if(k == listSize-1) {
                            purposeProperty += list.at(k);
                            break;
                        }
                        purposeProperty += list.at(k) + ".";
                    }
                    //purposeObjName查找对应对象属性,目的item
                    GY_Object* purObj = nullptr;
                    purObj = getPurObject(purposeObjName, purObj, m_ChildrensMap);
                    //找不到目的属性名称，返回哪个属性名称找不到
                    if(purObj == nullptr) {
                        return;
                    }
                    purObj->updateProperty(purposeProperty,val);
                }
            },Qt::UniqueConnection);

            QVariant value;
            QStringList list = m_biMap[tmpValueVec.at(i)].pointName.split(".");
            //属性名称
            QString property;
            //点类型不需要加点后面的xy, position.x为position
            if(m_biMap[tmpValueVec.at(i)].varType == PointPropertyType) {
                property += list.at(1);
            }else {
                int listSize = list.size();
                for(int k=1;k<listSize;k++) {
                    if(k == listSize-1) {
                        property += list.at(k);
                        break;
                    }
                    property += list.at(k) + ".";
                }
            }
            connectObj->getProperty(property, value);
            connectObj->updateProperty(property, value);

            if(m_ExecutionInformation != "OK") {
                //删除本次绑定信息
                int tmpValueVecSize = tmpValueVec.size();
                for(int j=0;j<tmpValueVecSize;j++) {
                    int index = m_biMap[tmpValueVec.at(j)].source.indexOf("return " + source);
                    m_biMap[tmpValueVec.at(j)].value.removeAt(index);
                    m_biMap[tmpValueVec.at(j)].purpose.removeAt(index);
                    m_biMap[tmpValueVec.at(j)].source.removeAt(index);
                }
                QString tmp = m_ExecutionInformation;
                m_ExecutionInformation = "OK";
                obj->isBind.remove(purposeProperty);
                return tmp;
            }
        }else {
            QVariant value;
            this->getProperty(tmpValueVec.at(i), value);
            this->updateProperty(tmpValueVec.at(i), value);

            if(m_ExecutionInformation != "OK") {
                //删除本次绑定信息
                int tmpValueVecSize = tmpValueVec.size();
                for(int j=0;j<tmpValueVecSize;j++) {
                    int index = m_biMap[tmpValueVec.at(j)].source.indexOf("return " + source);
                    m_biMap[tmpValueVec.at(j)].value.removeAt(index);
                    m_biMap[tmpValueVec.at(j)].purpose.removeAt(index);
                    m_biMap[tmpValueVec.at(j)].source.removeAt(index);
                }
                QString tmp = m_ExecutionInformation;
                m_ExecutionInformation = "OK";
                obj->isBind.remove(purposeProperty);
                return tmp;
            }
        }
    }
    if(copy == 0) {
        if(m_bindInformationMap.contains(m_source)) {
            m_bindInformationMap[m_source].push_back(m_purpose);
        }else {
            QVector<QString> pur;
            pur.push_back(m_purpose);
            m_bindInformationMap.insert(m_source, pur);
        }
    }

    return "OK";
}
//复制组绑定信息，删除原版绑定后，复制品绑定信息也应该全部删除
QString GY_ObjectGroup::removeDataBinding(const QString &purpose)
{
    //获取复制组复制图形的指针
    GY_Object* obj = nullptr;
    obj = getPurObject(purpose.split(".").at(0), obj, m_ChildrensMap);
    //找不到目的属性名称，返回哪个属性名称找不到
    if(obj == nullptr) {
        return QString(purpose + ": does not exist!");
    }

    QString property;
    QStringList list = purpose.split(".");
    int listSize = list.size();
    for(int i=1;i<listSize;i++) {
        if(i == listSize-1) {
            property += list.at(i);
            break;
        }
        property += list.at(i) + ".";
    }

    //获取图形复制个数
//    this->disconnect() 断关联
    int repeatNum = obj->getRepeatNum();
    for(int i=0;i<=repeatNum;i++) {
        //目的属性替换
        QString purposeChange = purpose;
        //替换为复制品的名称
        purposeChange.replace(purpose.split(".").at(0), QString(purpose.split(".").at(0)+"_+_=_%1").arg(i));
        removeDataBinding(purposeChange);
    }

    //被绑属性唯一，找出m_biMap中和purpose目的属性有关数据，全部删除
    QMap<QString,BindingInformation>::Iterator iter = m_biMap.begin();
    while (iter != m_biMap.end()) {
        for(int i=0;i<iter.value().purpose.size();i++) {
            if(iter.value().purpose.at(i) == purpose) {
                m_biMap[iter.key()].value.removeAt(i);
                m_biMap[iter.key()].purpose.removeAt(i);
                m_biMap[iter.key()].source.removeAt(i);
                QMap<QString,QVector<QString>>::Iterator iterInformation = m_bindInformationMap.begin();
                while (iterInformation != m_bindInformationMap.end()) {
                    for(int j=0;j<iterInformation.value().size();j++) {
                        if(iterInformation.value().at(j) == purpose) {
                            m_bindInformationMap[iterInformation.key()].removeAt(j);
                            //目的属性解除绑定
                            obj->isBind.remove(property);
                            return "OK";
                        }
                    }
                    iterInformation++;
                }
            }
        }
        ++iter;
    }
    return purpose + ": does not exist!";
}

void GY_ObjectGroup::removeAllItem()
{
    QMap<QString,GY_Object*>::Iterator iter = m_ChildrensMap.begin();
    while (iter != m_ChildrensMap.end()) {
        if(iter.value()->inherits("GY_BasicsGraphicsObject"))
        {
            this->removeFromGroup((GY_BasicsGraphicsObject*)iter.value());
        }
        else if(iter.value()->inherits("GY_ContainerTransform"))
        {
            this->removeFromGroup((GY_ContainerTransform*)iter.value());
        }
        ++iter;
    }
}

void GY_ObjectGroup::addAllItem()
{
    QMap<QString,GY_Object*>::Iterator iter = m_ChildrensMap.begin();
    while (iter != m_ChildrensMap.end()) {
        if(iter.value()->inherits("GY_BasicsGraphicsObject"))
        {
            this->addToGroup((GY_BasicsGraphicsObject*)iter.value());
        }
        else if(iter.value()->inherits("GY_ContainerTransform"))
        {
            this->addToGroup((GY_ContainerTransform*)iter.value());
        }
        ++iter;
    }
}

void GY_ObjectGroup::setGloabalVariable(const QString &source, const QVector<QString> &name,
                                                    const QVector<QString> &pointName, const QString &purpose)
{
    QString sourceR = "return " + source;
    int nameSize = name.size();
    for (int i=0;i<nameSize;i++) {
        //m_biMap里面没有该变量插入
        if(m_biMap.contains(name.at(i))) {
            m_biMap[name.at(i)].source.push_back(sourceR);
            //m_biMap存在name.at(i)，pointName、type、varType应该唯一且存在
            m_biMap[name.at(i)].purpose.push_back(purpose);
            m_biMap[name.at(i)].value.push_back(0);
        }else {
            BindingInformation a;
            a.source.push_back(sourceR);
            a.pointName = pointName.at(i);
            a.purpose.push_back(purpose);
            a.value.push_back(0);
            if(pointName.at(i).at(0) != '.') {
                a.type = 1;
                //注册全局变量
                QStringList list = pointName.at(i).split(".");
                QString sourceObjName = list.at(0);
                QString sourceProperty;
                int listSize = list.size();
                for(int k=1;k<listSize;k++) {
                    if(k == listSize-1) {
                        sourceProperty += list.at(k);
                        break;
                    }
                    sourceProperty += list.at(k) + ".";
                }
                if((list.at(listSize-1) == "X") || (list.at(listSize-1) == "Y")) {
                    sourceProperty = list.at(1);
                }
                //获取变量类型并且设置全局变量
                a.varType = getSourceType(sourceObjName,sourceProperty,name.at(i),m_ChildrensMap);
            }else {
                a.type = 0;
                a.varType = getPurposeType(purpose.split("."), m_ChildrensMap);
                //重复添加，insert再覆盖
                addAttribute(name.at(i),getQVariantType(a.varType));
            }
            m_biMap.insert(name.at(i),a);
        }
    }
}

GY_Object *GY_ObjectGroup::copyItem(const QString &guid)
{
    if(getUserData(GY_ENUM::IsCopy) == 1) {
        GY_Object *tmp;
        this->copyItemSig(&tmp);
        //添加自定义属性
        QMap<QString,QVariant>::Iterator iterAttribute = m_attributeMap.begin();
        while (iterAttribute != m_attributeMap.end()) {
            ((GY_ObjectGroup*)tmp)->addAttribute(iterAttribute.key(),iterAttribute.value());
            ++iterAttribute;
        }
        //更新copyItem属性列表
        QMap<QString,GY_PropertyInfo>::Iterator iterProperty = m_PropertyInfoMap.begin();
        while (iterProperty != m_PropertyInfoMap.end()) {
            if(((iterProperty.value().updateType)&PointOfRelative) == PointOfRelative) {
                tmp->updateProperty(iterProperty.key(), submittingPropertyValues(iterProperty.value().updateType,iterProperty.value().propertyValue,this));
            }else if(((iterProperty.value().updateType)&NotUpdate) == NotUpdate){
                ++iterProperty;
                continue;
            }else {
                tmp->updateProperty(iterProperty.key(), iterProperty.value().propertyValue);
            }
            ++iterProperty;
        }
        //绑定信息
//        QMap<QString,QVector<QString>>::Iterator iterBind = m_bindInformationMap.begin();
//        while (iterBind != m_bindInformationMap.end()) {
//            int iterBindValueSize = iterBind.value().size();
//            for(int i=0;i<iterBindValueSize;i++) {
//                QString source = iterBind.key();
//                ((GY_ObjectGroup*)tmp)->dataFlowEditor(source,iterBind.value().at(i));
//            }
//            ++iterBind;
//        }
        return tmp;
    }
    //映射返回一个新new的对象
    GY_Object* pObj;
    if(guid.isEmpty()) {
        pObj = (GY_Object*)GY_GraphicsReflection::getInstance()->newInstanceObjectClass(this->metaObject()->className(),this->getGuid()+"-"+QString::number(m_MyGuid));
        m_MyGuid++;
    }else {
        pObj = (GY_Object*)GY_GraphicsReflection::getInstance()->newInstanceObjectClass(this->metaObject()->className(),guid);
    }
    if(pObj == nullptr) {
        qDebug()<<this->getGuid()<<"isEmpty";
        return nullptr;
    }
    //按顺序添加子类
    QVector<GY_Object *> childrens = this->getOrderChildrens();
    int childrensSize = childrens.size();
    for(int i=0;i<childrensSize;i++) {
        ((GY_ContainerTransform*)pObj)->addItem(childrens[i]->copyItem());
    }
    //添加自定义属性
    QMap<QString,QVariant>::Iterator iterAttribute = m_attributeMap.begin();
    while (iterAttribute != m_attributeMap.end()) {
        ((GY_ObjectGroup*)pObj)->addAttribute(iterAttribute.key(),iterAttribute.value());
        ++iterAttribute;
    }
    //更新属性列表
    QMap<QString,GY_PropertyInfo>::Iterator iterProperty = m_PropertyInfoMap.begin();
    while (iterProperty != m_PropertyInfoMap.end()) {
        if(((iterProperty.value().updateType)&PointOfRelative) == PointOfRelative) {
            pObj->updateProperty(iterProperty.key(), submittingPropertyValues(iterProperty.value().updateType,iterProperty.value().propertyValue,this));
        }else if(((iterProperty.value().updateType)&NotUpdate) == NotUpdate){
            ++iterProperty;
            continue;
        }else {
            pObj->updateProperty(iterProperty.key(), iterProperty.value().propertyValue);
        }
        ++iterProperty;
    }
//    QMap<QString,BindingInformation>::iterator iterbind = m_biMap.begin();

    connect(pObj,&GY_Object::copyItemSig,this,&GY_Object::originalVersion);
    //复制品设置标志1，不可再复制
    pObj->setUserData(GY_ENUM::IsCopy, QVariant::fromValue(1));
    //绑定信息
    QMap<QString,QVector<QString>>::Iterator iterBind = m_bindInformationMap.begin();
    while (iterBind != m_bindInformationMap.end()) {
        int iterBindValueSize = iterBind.value().size();
        for(int i=0;i<iterBindValueSize;i++) {
            QString source = iterBind.key();
            ((GY_ObjectGroup*)pObj)->dataFlowEditor(source,iterBind.value().at(i));
        }
        ++iterBind;
    }
    return pObj;
}

QVector<QString> GY_ObjectGroup::getNewAttribute()
{
    return m_bindVec;
}

void GY_ObjectGroup::initializationPropertyInfo()
{
    GY_PropertyInfo ObjectName(this);
    ObjectName.propertyName = "ObjectName";
    ObjectName.propertyValue = QString();
    ObjectName.updateType = Update|OrdinaryAttributes;
    ObjectName.propertyType = QStringPropertyType;
    ObjectName.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_ObjectGroup::updateObjectName;
    m_PropertyInfoMap.insert(ObjectName.propertyName,ObjectName);
    m_PropertyInfoMap[ObjectName.propertyName].setConnect();

    //位置
    GY_PropertyInfo positonPropertyInfo(this);
    positonPropertyInfo.propertyName="Position";
    positonPropertyInfo.propertyValue=QPointF(0,0);
    positonPropertyInfo.updateType = Update|MoveUpdate|PointOfRelative;
    positonPropertyInfo.propertyType = PointPropertyType;
    positonPropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_ObjectGroup::updatePosition;
    m_PropertyInfoMap.insert(positonPropertyInfo.propertyName,positonPropertyInfo);
    m_PropertyInfoMap[positonPropertyInfo.propertyName].setConnect();
    m_pCalculationClass->formulaCalculation("Position", PointPropertyType);
    BindingInformation b;
    b.varType = PointPropertyType;
    m_biMap.insert("Position",b);

}

bool GY_ObjectGroup::updatePosition(const QString &name, const QVariant &value)
{
    if(!value.canConvert<QPointF>())
    {
        return false;
    }
//    qDebug() << "------------------" << this->getGuid() << this->getObjName() << name << value << "------------------";

    //setpos设置为父级坐标
    QPointF point = value.toPointF();
    if(this->parentItem()) {
        point = this->mapToParent(this->mapFromScene(value.toPointF()));
    }
    this->setPos(point);

    m_PropertyInfoMap[name].propertyValue=this->mapFromScene(value.toPointF());

    //如果没有这个name在里面，则该属性未绑定信息
    if((!m_biMap.contains(name)) && (m_biMap[name].source.size() != 0)) {
        return true;
    }
    //更改变量值
    m_pCalculationClass->propertyChange(name,m_PropertyInfoMap[name].propertyValue,getType(m_PropertyInfoMap[name].propertyValue));
    QString executionInformation = m_pCalculationClass->getSourceValue(m_biMap,name);
    if(executionInformation != "OK") {
        //数学表达式有错误
        emit executionInformationSig(executionInformation);
        return true;
    }

    int bindSize = m_biMap[name].source.size();
    for(int j=0;j<bindSize;j++) {
            QVariant val = m_biMap[name].value.at(j);
            QString pur = m_biMap[name].purpose.at(j);
            QStringList list = pur.split(".");
            QString purposeObjName = list.at(0);
            QString property;

            for(int k=1;k<list.size();k++) {
                if(k == list.size()-1) {
                    property += list.at(k);
                    break;
                }
                property += list.at(k) + ".";
            }

            //purposeObjName查找对应对象属性,目的item
            GY_Object* obj = nullptr;
            obj = getPurObject(purposeObjName, obj, m_ChildrensMap);
            //找不到目的属性名称，返回哪个属性名称找不到
            if(obj == nullptr) {
                return false;
            }
            obj->updateProperty(property,val);
    }
    return true;
}

bool GY_ObjectGroup::updateAttribute(const QString &name, const QVariant &value)
{
    if(m_PropertyInfoMap[name].propertyType != getType(value))
    {
        return false;
    }
    m_PropertyInfoMap[name].propertyValue=value;
    if((!m_biMap.contains(name)) && (m_biMap[name].source.size() != 0)) {
        return true;
    }

    m_pCalculationClass->propertyChange(name,value,getType(value));
    QString executionInformation = m_pCalculationClass->getSourceValue(m_biMap,name);
    if(executionInformation != "OK") {
        //数学表达式有错误
        emit executionInformationSig(executionInformation);
        return true;
    }

    int bindSize = m_biMap[name].source.size();
    for(int j=0;j<bindSize;j++) {
        QVariant val = m_biMap[name].value.at(j);
        QString pur = m_biMap[name].purpose.at(j);
        QStringList list = pur.split(".");
        QString purposeObjName = list.at(0);
        QString property;

        int listSize = list.size();
        for(int k=1;k<listSize;k++) {
            if(k == listSize-1) {
                property += list.at(k);
                break;
            }
            property += list.at(k) + ".";
        }

        //purposeObjName查找对应对象属性,目的item
        GY_Object* obj = nullptr;
        obj = getPurObject(purposeObjName, obj, m_ChildrensMap);
        //找不到目的属性名称，返回哪个属性名称找不到
        if(obj == nullptr) {
            return false;
        }
        obj->updateProperty(property,val);
    }
    return true;
}

PropertyType GY_ObjectGroup::getType(const QVariant &value)
{
    if(QString(value.typeName()) == "float") {
        return FloatPropertyType;
    }else if(QString(value.typeName()) == "QPointF") {
        return PointPropertyType;
    }else if(QString(value.typeName()) == "QColor") {
        return ColorPropertyType;
    }else if(QString(value.typeName()) == "int") {
        return IntPropertyType;
    }else if(QString(value.typeName()) == "QString") {
        return QStringPropertyType;
    }else if(QString(value.typeName()) == "qreal") {
        return QrealPropertyType;
    }else if(QString(value.typeName()) == "bool") {
        return BoolPropertyType;
    }
    return DoublePropertyType;
}

bool GY_ObjectGroup::checkProName(const QStringList &list)
{
    if(list.size() == 1) {
        return true;
    }
    if(list.size() == 2) {
        if(m_PropertyInfoMap.contains(list.at(0)) && m_PropertyInfoMap[list.at(0)].propertyType == PointPropertyType) {
            if((list.at(1) == "X") || (list.at(1) == "Y")) {
                return true;
            }
        }
    }
    return false;
}

GY_Object *GY_ObjectGroup::getProObject(const QString &name, GY_Object *obj, QMap<QString, GY_Object *> childrensMap)
{
    QMap<QString,GY_Object*>::Iterator iterName = childrensMap.begin();
    while (iterName != childrensMap.end()) {
        QStringList list = m_biMap[name].pointName.split(".");
        //item名称
        QString sourceObjName = list.at(0);
        //根据sourceObjName源对象名称找出相匹配objName的对象指针obj。
        QString objName = iterName.value()->getObjName();
        if(objName == sourceObjName) {
            return iterName.value();
        }
        //如果子类中有容器，再从容器中查找
        if(iterName.value()->getUserData(GY_ENUM::ObjectType) == 1) {
            obj = getProObject(name, obj, ((GY_ContainerTransform*)iterName.value())->getChildrensMap());
            if(obj != nullptr) {
                return obj;
            }
        }
        ++iterName;
    }
    return obj;
}

PropertyType GY_ObjectGroup::getSourceType(const QString &sourceObjName, const QString &sourceProperty, const QString &name, QMap<QString, GY_Object *> childrensMap)
{
    QMap<QString,GY_Object*>::Iterator iter = childrensMap.begin();
    while (iter != childrensMap.end()) {
        QVariant objName;
        objName = iter.value()->getObjName();
        if(objName == sourceObjName) {
            PropertyType type = iter.value()->getPropertyMap()[sourceProperty].propertyType;
            QVariant purValue;
            iter.value()->getProperty(sourceProperty,purValue);
            m_pCalculationClass->formulaCalculation(name, type);
            m_pCalculationClass->propertyChange(name, purValue, type);
            return type;
        }
        //如果子类中有容器，再从容器中查找
        if(iter.value()->getUserData(GY_ENUM::ObjectType) == 1) {
            PropertyType tmp = getSourceType(sourceObjName, sourceProperty, name, ((GY_ContainerTransform*)iter.value())->getChildrensMap());
            if(tmp != NullPropertyType) {
                return tmp;
            }
        }
        ++iter;
    }
    return NullPropertyType;
}

QVariant GY_ObjectGroup::getQVariantType(const PropertyType &type)
{
    if(type == ColorPropertyType) {
        return QColor(255,0,0);
    }else if(type == PointPropertyType) {
        return QPointF(0,0);
    }else if(type == IntPropertyType) {
        return int(0);
    }else if(type == QStringPropertyType) {
        return QString("string");
    }else if(type == BoolPropertyType) {
        return true;
    }
    return double(0);
}

bool GY_ObjectGroup::checkType(const PropertyType &type, const QVector<QString> &property, QMap<QString,GY_Object*> childrensMap)
{
    //点属性xy为double
    bool point = true;
    //遍历所有变量名称
    int size = property.size();
    for(int i=0;i<size;i++) {
        //不带点为子类属性
        if(property.at(i).at(0) != '.') {
            QStringList list = property.at(i).split(".");
            QString propertyObjName = list.at(0);
            QString propertyName;
            int listSize = list.size();
            for(int k=1;k<listSize;k++) {
                if(k == listSize-1) {
                    propertyName += list.at(k);
                    break;
                }
                propertyName += list.at(k) + ".";
            }
            if((list.at(listSize-1) == "X") || (list.at(listSize-1) == "Y")) {
                propertyName = list.at(1);
                point = false;
            }
            QMap<QString,GY_Object*>::Iterator iter = childrensMap.begin();
            while (iter != childrensMap.end()) {
                QVariant objName;
                objName = iter.value()->getObjName();
                if(objName == propertyObjName) {
                    PropertyType propertyType;
                    if(point) {
                        propertyType = iter.value()->getPropertyMap()[propertyName].propertyType;
                    }else {
                        //点的xy属性为double类型
                        propertyType = DoublePropertyType;
                    }
                    //找到返回是否匹配
                    if(!typeMatching(type,propertyType)) {
                        return false;
                    }else {
                        return true;
                    }
                }
                //如果子类中有容器，再从容器中查找
                if(iter.value()->getUserData(GY_ENUM::ObjectType) == 1) {
                    bool child = checkType(type, property, ((GY_ContainerTransform*)iter.value())->getChildrensMap());
                    if(!child) {
                        return false;
                    }else {
                        return true;
                    }
                }
                ++iter;
            }
        }
    }
    return true;
}

bool GY_ObjectGroup::typeMatching(const PropertyType &purType, PropertyType &proType)
{
    if((purType <= 5) && (proType <= 5)) {
        return true;
    }
    if((purType == QStringPropertyType) && (proType <= 5)) {
        return true;
    }
    if((proType == QStringPropertyType) && (purType <= 5)) {
        return true;
    }
    if(purType != proType) {
        return false;
    }
    return true;
}

bool GY_ObjectGroup::isPureNumber(const QString &str)
{
    std::string temp = str.toStdString();
    int length = str.length();
    for(int i=0;i<length;i++) {
        if(temp[i]<'0' || temp[i]>'9') {
            return false;
        }
    }
    return true;
}

bool GY_ObjectGroup::isSameProperty(const QString &purpose, const QString &source)
{
    if(purpose == source) {
        return true;
    }

    QStringList purposeList = purpose.split('.');
    QStringList sourceList = source.split('.');
    if((purposeList.size() == 3)&&(purposeList.at(0)==sourceList.at(0))&&(purposeList.at(1)==sourceList.at(1))) {
        if(purposeList.at(2)=='X' && sourceList.at(2)=='Y') {
            return true;
        }else if(purposeList.at(2)=='Y' && sourceList.at(2)=='X') {
            return true;
        }
    }
    return false;
}

void GY_ObjectGroup::getExecutionInformation(QString &executionInformation)
{
    m_ExecutionInformation = executionInformation;
}




